/*******************************************************************************
MPLAB Harmony Application Source File
Company:
Microchip Technology Inc.
File Name:
app.c
Summary:
This file contains the source code for the MPLAB Harmony application.
Description:
This file contains the source code for the MPLAB Harmony application. It
implements the logic of the application's state machine and it may call
API routines of other MPLAB Harmony modules in the system, such as drivers,
system services, and middleware. However, it does not call any of the
system interfaces (such as the "Initialize" and "Tasks" functions) of any of
the modules in the system or make any assumptions about when those functions
are called. That is the responsibility of the configuration-specific system
files.
*******************************************************************************/
// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved.
Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).
You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.
SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*******************************************************************************/
// DOM-IGNORE-END
// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************
//このプログラムは DMA0(U6RX→ramBuf[256] とDMA1(ramBuf[256]→U6TX)はチェイン連結されている。
//パターンマッチデータの'^'キャロットが U6RXに検出されるとU6TXの送信が行われる
#include "app.h"
#include <stdio.h>
SYS_DMA_CHANNEL_HANDLE channelHandle0;
SYS_DMA_CHANNEL_HANDLE channelHandle1;
unsigned char __attribute__((coherent)) ramBuf[256 + 1]; // transfer buffer
int delay_Clock = 200000000; //システムクロック:200MHz
char __attribute__((coherent)) Buf[32];
void delay_us(volatile unsigned int usec) //1μsec遅延
{
volatile int count;
count = (int)(delay_Clock/20000000)*usec;
do //実測 at 200MH (Clock=200000000)
{ //delay_us(1000):1000.4μsec delay_us(100):100.6μsec delay_us(10):10.5μsec delay_us(1):1.5μsec
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
count--;
}while(count != 0);
}
void delay_ms(volatile unsigned int msec) //1msec遅延
{
volatile unsigned int i; //実測:at200MH (Clock=200000000)//delay_ms(1): 1.0006msec delay_ms(100):100.04msec
for(i=0; i<msec; i++)
delay_us(1000);
}
void Write_Byte(char chr) //1バイト送信関数
{
PLIB_USART_TransmitterByteSend(USART_ID_6, chr); //送信バッファーに1バイト書込み・送信
// U6TXREG = chr; ////送信バッファーに1バイト書込み・送信
while (!PLIB_USART_TransmitterIsEmpty(USART_ID_6)); //送信バッファーが空になるまで待つ
//while(!U6STAbits.TRMT); //送信バッファーが空になるまで待つ
}
void WriteString(const char *str) //文字列送信関数
{
while(*str)
{
Write_Byte(*str); //データ送信
str++;
}
}
void myDMA_init(void)
{
//Harmony DMAライブラリ関数制御
channelHandle0 = SYS_DMA_ChannelAllocate(DMA_CHANNEL_0); //DMA0チャンネルオープン & ハンドル取得
channelHandle1 = SYS_DMA_ChannelAllocate(DMA_CHANNEL_1); //DMA0チャンネルオープン & ハンドル取得
SYS_DMA_ChannelTransferAdd(channelHandle0, (const void *)&U6RXREG, 1, (const void *)&ramBuf , 256, 1 ); //DMA0転送諸元設定
SYS_DMA_ChannelTransferAdd(channelHandle1, (const void *)&ramBuf, 256, (const void *)&U6TXREG, 1, 1 ); //DMA1転送諸元設定
SYS_DMA_ChannelSetup(
channelHandle0,
SYS_DMA_CHANNEL_OP_MODE_MATCH_ABORT | //パターンマッチ終了モード &
SYS_DMA_CHANNEL_OP_MODE_AUTO, //チャンネル自動起動モード
DMA_TRIGGER_USART_6_RECEIVE); //トリガ: U6RX 受信完了
SYS_DMA_ChannelSetup(
channelHandle1,
SYS_DMA_CHANNEL_OP_MODE_MATCH_ABORT | //パターンマッチ終了モード &
SYS_DMA_CHANNEL_OP_MODE_CHAIN_HIGH, //チャンネルチェインモード
DMA_TRIGGER_USART_6_TRANSMIT //トリガ: U6TxのバッファーU6TXREGにデータがレジスト(登録)完了となった時
);
SYS_DMA_ChannelSetupMatchAbortMode(channelHandle0, '^', // ^(キャロット)をパターンマッチデータにセット
DMA_PATTERN_MATCH_LENGTH_1BYTE, //パターンマッチデータは1バイト
SYS_DMA_CHANNEL_IGNORE_MATCH_DISABLE,
0);
SYS_DMA_ChannelSetupMatchAbortMode(channelHandle1, '^', // ^(キャロット)をパターンマッチデータにセット
DMA_PATTERN_MATCH_LENGTH_1BYTE, //パターンマッチデータは1バイト
SYS_DMA_CHANNEL_IGNORE_MATCH_DISABLE,
0);
//------------------------------------------------------------------------------------------------
////レジスタ直接制御
////割り込み優先度設定
//IPC33bits.DMA0IP = 5; //設定:IPL 5
//IPC33bits.DMA0IS = 2; //設定:sub-IPL 2
//IPC33bits.DMA1IP = 2; //設定:IPL 2
//IPC33bits.DMA1IS = 3; //設定:sub-IPL 2
//
//DCH0CONbits.CHAEN = 1; //チャンネル自動起動モード //必須 繰り返し用
//DCH0CONbits.CHEN = 1; //DCH0有効化 追加 //bit 7 CHEN: Channel Enable bit
//DCH0CONbits.CHPRI = 3; // CH0プライオリティ:3
//
//
//DCH1CONbits.CHAED = 1; //★チャンネル無効でもイベント動作可 //bit 6 CHAED: Channel Allow Events If Disabled bit
// //1 = Channel start/abort events will be registered, even if the channel is disabled
// //0 = Channel start/abort events will be ignored if the channel is disabled
//DCH1CONbits.CHCHN = 1; //★★★チャンネルチェイン //bit 5 CHCHN: Channel Chain Enable bit
// //1 = Allow channel to be chained
// //0 = Do not allow channel to be chained
//DCH1CONbits.CHPRI = 2; //チャンネルプライオリティ:2 //bit 1-0 CHPRI<1:0>: Channel Priority bits
//
//
//DCH0ECONbits.CHSIRQ = 189; //★スタートIRQ=189(U6RX) データシートより //★★★U6RX受信で割り込み発生
//DCH0ECONbits.PATEN = 1; //★パターンマッチ有効
//DCH0ECONbits.SIRQEN = 1; //★IRQスタート有効
////DCH0ECON=(189 <<8)| 0x30; // start IRQ is U6 RX, pattern enabled
//
//DCH1ECONbits.CHSIRQ = 190; //★スタートIRQ= 190(U4TX) データシートより //★★★U6TXのバッファーU6TXREGにデータが書き込まれると割り込み発生
//DCH1ECONbits.PATEN = 1; //★パターンマッチ有効
//DCH1ECONbits.SIRQEN = 1; //★IRQスタート有効
////DCH1ECON=(172 <<8)| 0x30; // start IRQ is U4 TX, pattern enabled
//
//DCH0DAT = '^'; // パターンマッチデータ //pattern value, carriage return
//DCH1DAT = '^'; // パターンマッチデータ //pattern value, carriage return
//
////チャンネル0 転送諸元 //program channel 0 transfer
//DCH0SSA = KVA_TO_PA((void*)(&U6RXREG)); //転送元アドレス // transfer source physical address
//DCH0DSA = KVA_TO_PA((void*)&ramBuf); //転送先アドレス // transfer destination physical address
//DCH0SSIZ = 1; //転送元サイズ //source size is 1 byte
//DCH0DSIZ = 256; //転送先サイズ // dst size at most 256 bytes
//DCH0CSIZ = 1; //転送サイズ(セルサイズ) // one byte per UART transfer request
//
////チャンネル1 転送諸元 //program channel 1 transfer
//DCH1SSA = KVA_TO_PA((void*)&ramBuf); //転送元アドレス // transfer source physical address
//DCH1DSA = KVA_TO_PA((void*)(&U6TXREG)); //転送先アドレス// transfer destination physical address
//DCH1SSIZ = 256; //転送元サイズ // source size at most 256 bytes
//DCH1DSIZ = 1; //転送先サイズ dst size is 1 byte
//DCH1CSIZ = 1; //転送サイズ(セルサイズ) one byte per UART transfer request
//
//
//DMACONbits.ON = 1; // DMAモジュールON
}
// *****************************************************************************
// *****************************************************************************
// Section: Global Data Definitions
// *****************************************************************************
// *****************************************************************************
// *****************************************************************************
/* Application Data
Summary:
Holds application data
Description:
This structure holds the application's data.
Remarks:
This structure should be initialized by the APP_Initialize function.
Application strings and buffers are be defined outside this structure.
*/
APP_DATA appData;
// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************
/* TODO: Add any necessary callback functions.
*/
// *****************************************************************************
// *****************************************************************************
// Section: Application Local Functions
// *****************************************************************************
// *****************************************************************************
/* TODO: Add any necessary local functions.
*/
// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************
/*******************************************************************************
Function:
void APP_Initialize ( void )
Remarks:
See prototype in app.h.
*/
void APP_Initialize ( void )
{
/* Place the App state machine in its initial state. */
appData.state = APP_STATE_INIT;
/* TODO: Initialize your application's state machine and other
* parameters.
*/
myDMA_init();
lcd_init(); // LCD初期化
lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF
lcd_clear();
lcd_cmd(0x80); //1目の先頭へ
sprintf(Buf,"DMA Match_Chain ");//
lcd_str(Buf); //液晶表示
lcd_cmd(0xC0); //2行目の先頭へ
sprintf(Buf," U6RX U6TX test "); //
lcd_str(Buf); // 開始メッセージ1行目表示
delay_ms(2000);
// //文字列送信
// WriteString("\rPattern Match \r\n");
// WriteString("Chained DMA0(U6Rx_RAM) and DMA1(RAM_U6Tx) \r\n");
}
/******************************************************************************
Function:
void APP_Tasks ( void )
Remarks:
See prototype in app.h.
*/
void APP_Tasks ( void )
{
/* Check the application's current state. */
switch ( appData.state )
{
/* Application's initial state. */
case APP_STATE_INIT:
{
bool appInitialized = true;
if (appInitialized)
{
appData.state = APP_STATE_SERVICE_TASKS;
}
break;
}
case APP_STATE_SERVICE_TASKS:
{
int i;
for(i = 0; i < 256; i++) // %c非表示文字をSpace表示化 //これを実行しないと制御が飛んでしまう。
{
if(((ramBuf[i] >= 0x00) && (ramBuf[i] <= 0x1F)) &&
(ramBuf[i] != '\r'))ramBuf[i] = ' '; //改行は除く
if(ramBuf[i] >= 0x80) ramBuf[i] = ' ';
}
lcd_cmd(0x80); //1目の先頭へ
sprintf(Buf,"RAM is below ");
lcd_str(Buf); //液晶表示
lcd_cmd(0xC0); //2行目の先頭へ
sprintf(Buf,"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
ramBuf[0],ramBuf[1],ramBuf[2],ramBuf[3],ramBuf[4],ramBuf[5],ramBuf[6],ramBuf[7],
ramBuf[8],ramBuf[9],ramBuf[10],ramBuf[11],ramBuf[12],ramBuf[13],ramBuf[14],ramBuf[15]);
lcd_str(Buf); // 開始メッセージ1行目表示
//----------------------------------------------------------------------------------
//★★ 以下、DCH0CONbits.CHAEN = 1; //[チャンネル自動起動モード] の代用として可
// SYS_DMA_ChannelEnable(channelHandle0); //DCH0有効化 //Harmony
// DCH0CONbits.CHEN = 1; //DMA0(U6RX -> RAM) //DCH0有効化
// DMACONbits.ON = 1; // DMAモジュールON
//----------------------------------------------------------------------------------
break;
}
/* TODO: implement your application state machine.*/
/* The default state should never be executed. */
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
/*******************************************************************************
End of File
*/